#ifndef _cesium_monitor_stage_hpp_
#define _cesium_monitor_stage_hpp_

#include "cesium/stage.hpp"
#include "cesium/buffer.hpp"
#include "cesium/sinkset.hpp"

namespace Cesium {

/** A stage which monitors an existing variable for changes. */
template<typename VarType>
class MonitorStage : public Stage {
public:
    MonitorStage(VarType* var) {
        buffer = new PinnedBuffer(var);
    }
    MonitorStage(VarType* var, Stage* sink) {
        buffer = new PinnedBuffer(var);
        sinks.add(sink);
    }
    virtual ~MonitorStage() {
        buffer->unref();
    }

    virtual void signal(Stage* src, Buffer* data, BufferRange range) {
        assert(false); // we should never get signaled since we have an external source
    }

    void signal() {
        fire();
    }
protected:
    /** Fires this stage, signaling the subsequent stages. */
    void fire() {
        sinks.signal(this, buffer);
    }

    Buffer* buffer;
    SinkSet sinks;
}; // class MonitorStage

} // namespace Cesium

#endif //_cesium_monitor_stage_hpp_
